// ImageEraser.vue - uni-app图片背景擦除和裁剪组件

<template>
    <view class="image-eraser-container">
        <!-- 图片编辑画布 -->
        <canvas class="eraser-canvas" canvas-id="eraserCanvas"
            :style="{ width: canvasWidth + 'px', height: canvasHeight + 'px' }" @touchstart="onTouchStart"
            @touchmove="onTouchMove" @touchend="onTouchEnd">
            
            <!-- 裁剪框 (当裁剪工具激活时显示) -->
            <view v-if="currentTool === 'crop'" class="crop-box" :style="{
                    left: cropBoxLeft + 'px',
                    top: cropBoxTop + 'px',
                    width: cropBoxWidth + 'px',
                    height: cropBoxHeight + 'px'
                }" @touchstart="onCropBoxTouchStart" @touchmove="onCropBoxTouchMove" @touchend="onCropBoxTouchEnd">
                <view class="crop-corner top-left" @touchstart.stop="onCornerTouchStart('topLeft')"></view>
                <view class="crop-corner top-right" @touchstart.stop="onCornerTouchStart('topRight')"></view>
                <view class="crop-corner bottom-left" @touchstart.stop="onCornerTouchStart('bottomLeft')"></view>
                <view class="crop-corner bottom-right" @touchstart.stop="onCornerTouchStart('bottomRight')"></view>
            </view>
        </canvas>

        <!-- 工具切换栏 -->
        <view class="tool-bar">
            <view class="tool-item" :class="{ active: currentTool === 'eraser' }" @click="selectTool('eraser')">
                <text>橡皮擦</text>
            </view>
            <view class="tool-item" :class="{ active: currentTool === 'crop' }" @click="selectTool('crop')">
                <text>裁剪</text>
            </view>
        </view>

        <!-- 橡皮擦工具控制面板 -->
        <view class="control-panel" v-if="currentTool === 'eraser'">
            <view class="brush-size-control">
                <text>橡皮擦大小: {{ brushSize }}px</text>
                <slider :min="5" :max="50" :value="brushSize" @change="onBrushSizeChange" show-value />
            </view>
        </view>

        <!-- 裁剪工具控制面板 -->
        <view class="control-panel" v-if="currentTool === 'crop'">
            <view class="crop-control">
                <text>裁剪尺寸:</text>
                <view class="crop-inputs">
                    <input type="number" v-model="cropWidth" placeholder="宽度" />
                    <text>x</text>
                    <input type="number" v-model="cropHeight" placeholder="高度" />
                </view>
            </view>
            <view class="crop-ratio-control">
                <text>预设比例:</text>
                <view class="crop-ratio-buttons">
                    <button size="mini" @click="setCropRatio(1, 1)">1:1</button>
                    <button size="mini" @click="setCropRatio(4, 3)">4:3</button>
                    <button size="mini" @click="setCropRatio(3, 4)">3:4</button>
                    <button size="mini" @click="setCropRatio(16, 9)">16:9</button>
                </view>
            </view>
            <button type="primary" @click="performCrop">应用裁剪</button>
        </view>

        <!-- 底部操作按钮组 -->
        <view class="button-group">
            <button type="default" @click="undo">撤销</button>
            <button type="default" @click="resetCanvas">重置</button>
            <button type="primary" @click="saveImage">保存</button>
        </view>
    </view>
</template>

<script>
export default {
    name: 'ImageEraser',
    props: {
        // 要处理的图片路径
        imageSrc: {
            type: String,
            required: true
        },
        // 画布宽度
        width: {
            type: Number,
            default: 300
        },
        // 画布高度
        height: {
            type: Number,
            default: 300
        }
    },
    data() {
        return {
            canvasWidth: 300,
            canvasHeight: 300,
            brushSize: 20,
            context: null,
            originalImageData: null,
            currentImageData: null,
            isDrawing: false,
            lastX: 0,
            lastY: 0,
            imageLoaded: false,

            // 工具选择
            currentTool: 'eraser', // 'eraser' 或 'crop'

            // 裁剪相关
            cropWidth: 200,
            cropHeight: 200,
            cropBoxLeft: 50,
            cropBoxTop: 50,
            cropBoxWidth: 200,
            cropBoxHeight: 200,
            isCropBoxDragging: false,
            isCornerDragging: false,
            activeCorner: null,
            dragStartX: 0,
            dragStartY: 0,
            initialCropBox: {
                left: 0,
                top: 0,
                width: 0,
                height: 0
            },

            // 图片信息
            imageInfo: {
                width: 0,
                height: 0,
                x: 0,
                y: 0,
                scale: 1
            },

            historyStates: [], // 用于存储历史状态
            maxHistoryLength: 10, // 最大历史记录数
        }
    },
    mounted() {
        // 初始化canvas和图片
        this.$nextTick(() => {
            this.initCanvas();
        });
    },
    methods: {
        // 初始化canvas
        initCanvas() {
            this.canvasWidth = this.width;
            this.canvasHeight = this.height;

            // 获取canvas上下文
            const ctx = uni.createCanvasContext('eraserCanvas', this);
            this.context = ctx;

            // 加载图片到canvas
            this.loadImage();
        },

        // 加载图片到canvas
        loadImage() {
            const that = this;

            // 确保图片路径有效
            if (!this.imageSrc) {
                uni.showToast({
                    title: '图片路径无效',
                    icon: 'none'
                });
                return;
            }

            // 获取图片信息
            uni.getImageInfo({
                src: this.imageSrc,
                success: (res) => {
                    // 保存图片信息
                    const imgWidth = res.width;
                    const imgHeight = res.height;

                    // 计算缩放比例
                    const scale = Math.min(
                        that.canvasWidth / imgWidth,
                        that.canvasHeight / imgHeight
                    );

                    // 计算居中位置
                    const x = (that.canvasWidth - imgWidth * scale) / 2;
                    const y = (that.canvasHeight - imgHeight * scale) / 2;

                    // 保存图片信息到实例
                    that.imageInfo = {
                        width: imgWidth,
                        height: imgHeight,
                        displayWidth: imgWidth * scale,
                        displayHeight: imgHeight * scale,
                        x: x,
                        y: y,
                        scale: scale
                    };

                    // 初始化裁剪框为图片大小
                    that.cropBoxLeft = x;
                    that.cropBoxTop = y;
                    that.cropBoxWidth = imgWidth * scale;
                    that.cropBoxHeight = imgHeight * scale;
                    that.cropWidth = Math.round(imgWidth);
                    that.cropHeight = Math.round(imgHeight);

                    // 绘制图片到canvas
                    that.context.drawImage(
                        that.imageSrc,
                        x,
                        y,
                        imgWidth * scale,
                        imgHeight * scale
                    );

                    that.context.draw(false, () => {
                        that.imageLoaded = true;
                        // 保存原始图像数据用于重置
                        that.captureImageData('original');

                        // 图片加载完成事件
                        that.$emit('imageLoaded');
                    });
                },
                fail: (err) => {
                    console.error('图片加载失败:', err);
                    uni.showToast({
                        title: '图片加载失败',
                        icon: 'none'
                    });
                }
            });
        },

        // 捕获图像数据
        captureImageData(type = 'current') {
            uni.canvasToTempFilePath({
                canvasId: 'eraserCanvas',
                success: (res) => {
                    if (type === 'original') {
                        this.originalImageData = res.tempFilePath;
                    }
                    this.currentImageData = res.tempFilePath;
                },
                fail: (err) => {
                    console.error('保存图像数据失败:', err);
                }
            }, this);
        },

        // 选择工具
        selectTool(tool) {
            this.currentTool = tool;
            console.log(this.imageInfo);
            

            // 当切换到裁剪工具时，确保裁剪框与当前图片位置对齐
            if (tool === 'crop') {
                // 使用图片的实际显示位置和尺寸
                this.cropBoxLeft = this.imageInfo.x;
                this.cropBoxTop = this.imageInfo.y;
                this.cropBoxWidth = this.imageInfo.displayWidth;
                this.cropBoxHeight = this.imageInfo.displayHeight;

                // 更新裁剪尺寸输入框
                this.cropWidth = Math.round(this.imageInfo.width);
                this.cropHeight = Math.round(this.imageInfo.height);
            }
        },

        // === 橡皮擦相关方法 ===

        // 触摸开始事件
        onTouchStart(e) {
            if (!this.imageLoaded) return;

            // 如果当前是裁剪工具，不处理擦除逻辑
            if (this.currentTool === 'crop') return;

            const touch = e.touches[0];
            const x = touch.x;
            const y = touch.y;

            this.isDrawing = true;
            this.lastX = x;
            this.lastY = y;

            // 开始擦除
            this.erase(x, y);
        },

        // 触摸移动事件
        onTouchMove(e) {
            if (!this.isDrawing || !this.imageLoaded || this.currentTool === 'crop') return;

            const touch = e.touches[0];
            const x = touch.x;
            const y = touch.y;

            // 连续擦除
            this.erase(x, y, this.lastX, this.lastY);

            this.lastX = x;
            this.lastY = y;
        },

        // 触摸结束事件
        onTouchEnd() {
            if (this.isDrawing) {
    this.isDrawing = false;
    // 保存当前状态
    this.captureImageData();
    // 保存到历史记录
    uni.canvasToTempFilePath({
      canvasId: 'eraserCanvas',
      success: (res) => {
        this.historyStates.push({
  tempFilePath: res.tempFilePath,
  imageInfo: JSON.parse(JSON.stringify(this.imageInfo))  // 深拷贝图像信息
});
        // 限制历史记录长度
        if (this.historyStates.length > this.maxHistoryLength) {
          this.historyStates.shift();
        }
      }
    }, this);
  }
        },

        // 擦除方法
        erase(x, y, lastX, lastY) {
            const ctx = this.context;

            // 设置合成模式为目标擦除
            ctx.globalCompositeOperation = 'destination-out';

            // 设置画笔样式
            ctx.lineWidth = this.brushSize;
            ctx.lineCap = 'round';
            ctx.lineJoin = 'round';

            if (lastX && lastY) {
                // 如果有上一个点，则画线
                ctx.beginPath();
                ctx.moveTo(lastX, lastY);
                ctx.lineTo(x, y);
                ctx.stroke();
            } else {
                // 否则画点
                ctx.beginPath();
                ctx.arc(x, y, this.brushSize / 2, 0, Math.PI * 2);
                ctx.fill();
            }

            ctx.draw(true);
        },

        // 调整橡皮擦大小
        onBrushSizeChange(e) {
            this.brushSize = e.detail.value;
        },

        // === 裁剪相关方法 ===

        // 设置裁剪比例
        setCropRatio(widthRatio, heightRatio) {
            const ratio = widthRatio / heightRatio;

            // 保持裁剪框中心不变
            const centerX = this.cropBoxLeft + this.cropBoxWidth / 2;
            const centerY = this.cropBoxTop + this.cropBoxHeight / 2;

            // 确定新的裁剪框尺寸，保持在画布范围内
            let newWidth = this.cropBoxHeight * ratio;
            let newHeight = this.cropBoxHeight;

            // 如果宽度超出边界，调整高度
            if (newWidth > this.canvasWidth) {
                newWidth = this.canvasWidth * 0.9;
                newHeight = newWidth / ratio;
            }

            // 更新裁剪框尺寸和位置
            this.cropBoxWidth = newWidth;
            this.cropBoxHeight = newHeight;
            this.cropBoxLeft = centerX - newWidth / 2;
            this.cropBoxTop = centerY - newHeight / 2;

            // 确保裁剪框在画布内
            this.constrainCropBoxToCanvas();

            // 更新输入框的值
            this.updateCropDimensions();
        },

        // 更新裁剪尺寸到输入框
        updateCropDimensions() {
            // 计算实际裁剪尺寸（考虑缩放比例）
            const actualWidth = Math.round(this.cropBoxWidth / this.imageInfo.scale);
            const actualHeight = Math.round(this.cropBoxHeight / this.imageInfo.scale);

            this.cropWidth = actualWidth;
            this.cropHeight = actualHeight;
        },

        // 限制裁剪框在画布内
        constrainCropBoxToCanvas() {
            return
            // 限制左边界
            if (this.cropBoxLeft < 0) {
                this.cropBoxLeft = 0;
            }

            // 限制上边界
            if (this.cropBoxTop < 0) {
                this.cropBoxTop = 0;
            }

            // 限制右边界
            if (this.cropBoxLeft + this.cropBoxWidth > this.canvasWidth) {
                this.cropBoxWidth = this.canvasWidth - this.cropBoxLeft;
            }

            // 限制下边界
            if (this.cropBoxTop + this.cropBoxHeight > this.canvasHeight) {
                this.cropBoxTop = this.canvasHeight - this.cropBoxHeight;
            }
        },

        // 裁剪框触摸开始
        onCropBoxTouchStart(e) {
            if (this.isCornerDragging) return;

            const touch = e.touches[0];
            this.dragStartX = touch.clientX;
            this.dragStartY = touch.clientY;

            // 记录初始裁剪框位置和尺寸
            this.initialCropBox = {
                left: this.cropBoxLeft,
                top: this.cropBoxTop,
                width: this.cropBoxWidth,
                height: this.cropBoxHeight
            };
        },

        // 裁剪框触摸移动
        onCropBoxTouchMove(e) {
            if (!this.isCropBoxDragging) return;

            const touch = e.touches[0];
            const deltaX = touch.clientX - this.dragStartX;
            const deltaY = touch.clientY - this.dragStartY;

            // 更新裁剪框位置
            this.cropBoxLeft = this.initialCropBox.left + deltaX;
            this.cropBoxTop = this.initialCropBox.top + deltaY;

            // 确保裁剪框在画布内
            this.constrainCropBoxToCanvas();
        },

        // 裁剪框触摸结束
        onCropBoxTouchEnd() {
            this.isCropBoxDragging = false;
        },

        // 角落触摸开始
        onCornerTouchStart(corner) {
            const touch = event.touches[0];
            this.isCornerDragging = true;
            this.activeCorner = corner;
            this.dragStartX = touch.clientX;
            this.dragStartY = touch.clientY;

            // 记录初始裁剪框信息
            this.initialCropBox = {
                left: this.cropBoxLeft,
                top: this.cropBoxTop,
                width: this.cropBoxWidth,
                height: this.cropBoxHeight
            };
        },

        // 裁剪框角落拖拽处理
        onCropBoxTouchMove(e) {
            if (this.isCornerDragging) {
                // 处理角落拖拽
                this.handleCornerDrag(e);
            } else if (this.isCropBoxDragging) {
                // 处理整个裁剪框拖拽
                const touch = e.touches[0];
                const deltaX = touch.clientX - this.dragStartX;
                const deltaY = touch.clientY - this.dragStartY;

                // 更新裁剪框位置
                this.cropBoxLeft = this.initialCropBox.left + deltaX;
                this.cropBoxTop = this.initialCropBox.top + deltaY;

                // 确保裁剪框在画布内
                this.constrainCropBoxToCanvas();
            }
        },

        // 处理角落拖拽
        handleCornerDrag(e) {
            const touch = e.touches[0];
            const deltaX = touch.clientX - this.dragStartX;
            const deltaY = touch.clientY - this.dragStartY;

            const init = this.initialCropBox;

            // 根据不同角落更新裁剪框
            switch (this.activeCorner) {
                case 'topLeft':
                    this.cropBoxLeft = init.left + deltaX;
                    this.cropBoxTop = init.top + deltaY;
                    this.cropBoxWidth = init.width - deltaX;
                    this.cropBoxHeight = init.height - deltaY;
                    break;
                case 'topRight':
                    this.cropBoxTop = init.top + deltaY;
                    this.cropBoxWidth = init.width + deltaX;
                    this.cropBoxHeight = init.height - deltaY;
                    break;
                case 'bottomLeft':
                    this.cropBoxLeft = init.left + deltaX;
                    this.cropBoxWidth = init.width - deltaX;
                    this.cropBoxHeight = init.height + deltaY;
                    break;
                case 'bottomRight':
                    this.cropBoxWidth = init.width + deltaX;
                    this.cropBoxHeight = init.height + deltaY;
                    break;
            }

            // 确保宽高不小于最小值
            if (this.cropBoxWidth < 20) this.cropBoxWidth = 20;
            if (this.cropBoxHeight < 20) this.cropBoxHeight = 20;

            // 确保裁剪框在画布内
            this.constrainCropBoxToCanvas();

            // 更新输入框的尺寸值
            this.updateCropDimensions();
        },

        // 裁剪框触摸结束
        onCropBoxTouchEnd() {
            this.isCropBoxDragging = false;
            this.isCornerDragging = false;
            this.activeCorner = null;
        },

        // 执行裁剪 - 修复后的方法
        performCrop() {
            if (!this.imageLoaded) return;

            // 保存当前canvas状态到历史记录
            uni.canvasToTempFilePath({
                canvasId: 'eraserCanvas',
                success: (res) => {
                    this.historyStates.push(res.tempFilePath);
                    if (this.historyStates.length > this.maxHistoryLength) {
                        this.historyStates.shift();
                    }
                }
            }, this);

            // 计算相对于原始图像的裁剪区域坐标
            // 将画布上的裁剪框位置转换为图像上的实际位置
            const relativeX = (this.cropBoxLeft - this.imageInfo.x) / this.imageInfo.scale;
            const relativeY = (this.cropBoxTop - this.imageInfo.y) / this.imageInfo.scale;
            const relativeWidth = this.cropBoxWidth / this.imageInfo.scale;
            const relativeHeight = this.cropBoxHeight / this.imageInfo.scale;

            // 安全检查：确保裁剪参数有效
            if (relativeX < 0 || relativeY < 0 ||
                relativeX + relativeWidth > this.imageInfo.width ||
                relativeY + relativeHeight > this.imageInfo.height) {
                uni.showToast({
                    title: '裁剪区域超出图片范围',
                    icon: 'none'
                });
                return;
            }

            // 清空画布
            this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

            // 计算新的缩放和位置，使裁剪后的图像居中显示
            const newScale = Math.min(
                this.canvasWidth / relativeWidth,
                this.canvasHeight / relativeHeight
            );

            const newX = (this.canvasWidth - relativeWidth * newScale) / 2;
            const newY = (this.canvasHeight - relativeHeight * newScale) / 2;

            // 绘制裁剪后的图像
            this.context.drawImage(
                this.currentImageData,
                relativeX, relativeY, relativeWidth, relativeHeight,
                newX, newY, relativeWidth * newScale, relativeHeight * newScale
            );

            this.context.draw(false, () => {
                // 更新图像信息
                this.imageInfo = {
                    width: relativeWidth,
                    height: relativeHeight,
                    displayWidth: relativeWidth * newScale,
                    displayHeight: relativeHeight * newScale,
                    x: newX,
                    y: newY,
                    scale: newScale
                };

                // 更新裁剪框
                this.cropBoxLeft = newX;
                this.cropBoxTop = newY;
                this.cropBoxWidth = relativeWidth * newScale;
                this.cropBoxHeight = relativeHeight * newScale;

                // 捕获新的图像状态
                this.captureImageData();

                uni.showToast({
                    title: '裁剪成功',
                    icon: 'success'
                });
            });
        },
        // 计算裁剪参数
        calculateCropParams() {
            return {
                x: this.cropBoxLeft,
                y: this.cropBoxTop,
                width: this.cropBoxWidth,
                height: this.cropBoxHeight
            };
        },

        // 重置canvas到原始图像
        resetCanvas() {
            if (!this.originalImageData) {
                this.loadImage();
                return;
            }

            const ctx = this.context;
            ctx.globalCompositeOperation = 'source-over';
            ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

            // 恢复原始图片
            uni.getImageInfo({
                src: this.originalImageData,
                success: (res) => {
                    // 重新加载图片信息
                    const imgWidth = res.width;
                    const imgHeight = res.height;

                    // 计算缩放比例
                    const scale = Math.min(
                        this.canvasWidth / imgWidth,
                        this.canvasHeight / imgHeight
                    );

                    // 计算居中位置
                    const x = (this.canvasWidth - imgWidth * scale) / 2;
                    const y = (this.canvasHeight - imgHeight * scale) / 2;

                    // 更新图片信息
                    this.imageInfo = {
                        width: imgWidth,
                        height: imgHeight,
                        displayWidth: imgWidth * scale,
                        displayHeight: imgHeight * scale,
                        x: x,
                        y: y,
                        scale: scale
                    };

                    // 重新绘制原始图片
                    ctx.drawImage(this.originalImageData, x, y, imgWidth * scale, imgHeight * scale);
                    ctx.draw();

                    // 重置裁剪框
                    this.cropBoxLeft = x;
                    this.cropBoxTop = y;
                    this.cropBoxWidth = imgWidth * scale;
                    this.cropBoxHeight = imgHeight * scale;
                    this.cropWidth = Math.round(imgWidth);
                    this.cropHeight = Math.round(imgHeight);
                }
            });
        },

        // 保存处理后的图像
        saveImage() {
            uni.canvasToTempFilePath({
                canvasId: 'eraserCanvas',
                fileType: 'png', // 使用PNG格式保留透明度
                success: (res) => {
                    const tempFilePath = res.tempFilePath;

                    // 发送保存好的图片路径给父组件
                    this.$emit('imageSaved', tempFilePath);

                    uni.showToast({
                        title: '图片保存成功',
                        icon: 'success'
                    });
                },
                fail: (err) => {
                    console.error('图片保存失败:', err);
                    uni.showToast({
                        title: '图片保存失败',
                        icon: 'none'
                    });
                }
            }, this);
        },

        // 撤销方法
        undo() {
            if (this.historyStates.length > 0) {
                const previousState = this.historyStates.pop();
                
                // 恢复到上一个状态
                // this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
                
                this.imageInfo = previousState.imageInfo;  // 恢复图像信息
                // 使用图像的实际位置和尺寸进行绘制
                this.context.drawImage(
                    previousState.tempFilePath, 
                    this.imageInfo.x, 
                    this.imageInfo.y, 
                    this.imageInfo.displayWidth, 
                    this.imageInfo.displayHeight
                );
                
                this.context.draw(false, () => {
                    console.log('撤销操作完成');
                });
            } else {
                uni.showToast({
                title: '没有可撤销的操作',
                icon: 'none'
                });
            }
        },
    }
}
</script>

<style>
.image-eraser-container {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 30rpx;
    position: relative;
    background-color: #f8f8f8;
    border-radius: 12rpx;
    box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
}

.eraser-canvas {
    border: 2rpx solid #e0e0e0;
    border-radius: 8rpx;
    box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
    background-color: transparent;
    /* 棋盘格背景，用于显示透明区域 */
    background-image:
        linear-gradient(45deg, #f0f0f0 25%, transparent 25%),
        linear-gradient(-45deg, #f0f0f0 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #f0f0f0 75%),
        linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);
    background-size: 20rpx 20rpx;
    background-position: 0 0, 0 10rpx, 10rpx -10rpx, -10rpx 0rpx;
    margin-bottom: 20rpx;
}

.tool-bar {
    display: flex;
    justify-content: center;
    width: 100%;
    margin: 16rpx 0;
    padding: 12rpx 0;
    background-color: #ffffff;
    border-radius: 8rpx;
    box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05);
}

.tool-item {
    padding: 14rpx 28rpx;
    border: 1rpx solid #e4e4e4;
    border-radius: 30rpx;
    background-color: #ffffff;
    margin: 0 15rpx;
    font-size: 28rpx;
    transition: all 0.3s ease;
}

.tool-item.active {
    background-color: #007aff;
    color: white;
    border-color: #007aff;
    box-shadow: 0 2rpx 8rpx rgba(0, 122, 255, 0.3);
    transform: scale(1.05);
}

.control-panel {
    width: 100%;
    margin: 16rpx 0;
    padding: 20rpx;
    border: 1rpx solid #e8e8e8;
    border-radius: 10rpx;
    background-color: #ffffff;
    box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
}

.brush-size-control {
    margin-bottom: 16rpx;
}

.brush-size-control text {
    font-size: 28rpx;
    color: #333;
    margin-bottom: 10rpx;
    display: block;
}

.brush-size-control slider {
    margin: 20rpx 0;
}

.crop-control {
    margin-bottom: 16rpx;
}

.crop-control text {
    font-size: 28rpx;
    color: #333;
}

.crop-inputs {
    display: flex;
    align-items: center;
    margin-top: 14rpx;
}

.crop-inputs input {
    border: 1rpx solid #e0e0e0;
    border-radius: 6rpx;
    padding: 8rpx 12rpx;
    width: 120rpx;
    margin: 0 10rpx;
    text-align: center;
    font-size: 28rpx;
    background-color: #f9f9f9;
}

.crop-ratio-control {
    margin: 16rpx 0;
}

.crop-ratio-control text {
    font-size: 28rpx;
    color: #333;
}

.crop-ratio-buttons {
    display: flex;
    flex-wrap: wrap;
    margin-top: 14rpx;
}

.crop-ratio-buttons button {
    margin: 6rpx;
    min-width: 100rpx;
    font-size: 24rpx;
    border-radius: 30rpx;
    background-color: #f5f5f5;
    color: #333;
}

.crop-ratio-buttons button:active {
    background-color: #e0e0e0;
}

.button-group {
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin-top: 24rpx;
}

.button-group button {
    width: 45%;
    border-radius: 40rpx;
    padding: 16rpx 0;
    font-size: 30rpx;
    display: flex;
    align-items: center;
    justify-content: center;
}

.button-group button:first-child {
    background-color: #f5f5f5;
    color: #333;
    border: 1rpx solid #e0e0e0;
}

.button-group button[type="primary"] {
    background: linear-gradient(135deg, #0088ff, #007aff);
    box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.3);
}

.crop-box {
    position: absolute;
    border: 2rpx dashed rgba(0, 122, 255, 0.8);
    background-color: rgba(0, 122, 255, 0.1);
    box-sizing: border-box;
    pointer-events: all;
}

.crop-corner {
    position: absolute;
    width: 24rpx;
    height: 24rpx;
    background-color: #ffffff;
    border: 2rpx solid #007aff;
    border-radius: 50%;
    box-shadow: 0 0 6rpx rgba(0, 0, 0, 0.2);
}

.top-left {
    top: -12rpx;
    left: -12rpx;
    cursor: nwse-resize;
}

.top-right {
    top: -12rpx;
    right: -12rpx;
    cursor: nesw-resize;
}

.bottom-left {
    bottom: -12rpx;
    left: -12rpx;
    cursor: nesw-resize;
}

.bottom-right {
    bottom: -12rpx;
    right: -12rpx;
    cursor: nwse-resize;
}

/* 增加功能提示信息样式 */
.tip-text {
    font-size: 24rpx;
    color: #888;
    margin: 10rpx 0;
    text-align: center;
}

/* 加载状态样式 */
.loading-mask {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(255, 255, 255, 0.7);
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    z-index: 999;
}

.loading-text {
    margin-top: 20rpx;
    font-size: 28rpx;
    color: #007aff;
}
</style>
